package com.zhangtao.demo.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.zhangtao.demo.common.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.io.Files;
import com.zhangtao.demo.common.config.GloableConfig;
import com.zhangtao.demo.common.enums.ResultStatus;
import com.zhangtao.demo.common.vo.JsonResponseEntity;
import com.zhangtao.demo.common.vo.VoiceRecord;

@RestController
@RequestMapping(value = "util")
public class UtilController {
	private static Logger logger = LogManager.getLogger(UtilController.class);
	@Autowired
	private GloableConfig gconfig;
	public static final String ffmpegPath = "D://workspace/ffmpeg-20181028-e95987f-win64-static/bin";
	public static final String convertPath = "D://workspace/ffmpeg_convert/audio";
	private File dir = new File(ffmpegPath);
	private File targetOutDir = new File(convertPath);
	@Autowired
	private BaiduSpeechApi baiduSpeech;
	@Value("${baiduaip.speech.supportlist}")
	private String speechSupportList;
	@Autowired
	private BaiduAipImageClassifyClient baiduImage;

	private final static String excel2003L = "xls"; // 2003- 版本的excel
	private final static String excel2007U = "xlsx"; // 2007+ 版本的excel

	private ExecutorService cachedPool = Executors.newCachedThreadPool();

	@RequestMapping(value = "/md5", method = RequestMethod.GET)
	public String getMd5Str(@RequestParam String param) {
		return MD5.encode(param);
	}

	@RequestMapping(value = "/currentTimeMillis", method = RequestMethod.GET)
	public String currentTimeStamp() {
		return System.currentTimeMillis() + "";
	}

	@RequestMapping(value = "wavConvertToPcm", method = RequestMethod.POST)
	public String wavConvertToPcm(@RequestParam(value = "f") MultipartFile f) {
		try {
			if (!targetOutDir.exists()) {
				targetOutDir.mkdirs();
			}
			long now = System.currentTimeMillis();
			File wav = new File(targetOutDir, now + ".wav");
			if (f != null) {
				IOUtil.transferToTargetFile(f.getInputStream(), wav);
			}
			File pcm = new File(targetOutDir, now + ".pcm");
			String cmd = "cmd /c start ffmpeg -y  -i " + wav.getAbsolutePath()
					+ "  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 " + pcm.getAbsolutePath();
			Process p = Runtime.getRuntime().exec(cmd, null, dir);
			InputStream in = p.getInputStream();
			StringBuffer sb = new StringBuffer();
			byte[] b = new byte[1024];
			while (in.read(b) > 0) {
				sb.append(new String(b, Charset.forName("utf-8")));
			}
			System.out.println(sb);
			in.close();
			p.destroy();
			return pcm.getAbsolutePath();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	@RequestMapping(value = "/baiduspeech", method = RequestMethod.POST)
	@ResponseBody
	public com.alibaba.fastjson.JSONObject badiSpeech(@RequestParam(value = "f") MultipartFile f) {
		com.alibaba.fastjson.JSONObject result = new com.alibaba.fastjson.JSONObject();
		try {
			String originFileName = f.getOriginalFilename();
			String[] n = originFileName.split("\\.");
			String type = null;
			if (n.length > 1) {
				type = n[n.length - 1];
			}
			if (type != null && type.length() > 0) {
				if (speechSupportList.contains(type)) {
					JSONObject res = baiduSpeech.asr(f.getBytes(), type);
					if (res != null) {
						result = com.alibaba.fastjson.JSONObject.parseObject(res.toString(2));
					}
				} else {
					result.put("data", "类型不支持");
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	@RequestMapping(value = "/baiduImage", method = RequestMethod.POST)
	@ResponseBody
	public com.alibaba.fastjson.JSONObject badiImage(@RequestParam(value = "f") MultipartFile f) {
		com.alibaba.fastjson.JSONObject result = null;
		if (f == null || f.isEmpty()) {
			return null;
		}
		try {
			JSONObject res = baiduImage.advancedGeneralByte(f.getBytes());
			result = com.alibaba.fastjson.JSONObject.parseObject(res.toString(2));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	@RequestMapping(value = "/excelImport", method = RequestMethod.POST)
	public JsonResponseEntity<Object> acceptExcelFile(@RequestParam(value = "file") MultipartFile excel) {
		if (excel == null) {
			return new JsonResponseEntity<Object>(ResultStatus.SYSTEM_EXP, "file is empty");
		}
		String fileName = excel.getOriginalFilename();
		String[] names = StringUtils.split(fileName, ".");

		try {
			InputStream input = excel.getInputStream();
			Workbook book = null;
			if (names != null && names.length > 1 && StringUtils.isNotEmpty(names[1])) {
				String fileType = names[1];
				if (excel2003L.equals(fileType)) {
					book = new HSSFWorkbook(input); // 2003-
				} else if (excel2007U.equals(fileType)) {
					book = new XSSFWorkbook(input); // 2007+
				}
			}
			if (book == null) {
				return new JsonResponseEntity<Object>(ResultStatus.SYSTEM_EXP, "unsport file");
			}
			// 得到第一个shell
			Sheet sheet = book.getSheetAt(0);
			// 得到Excel的行数
			int totalRows = sheet.getLastRowNum() + 1;
			LinkedList<VoiceRecord> vrList = new LinkedList<>();
			ArrayList<String> needTransferFile = new ArrayList<>(totalRows * 3);
			for (int i = 1; i < totalRows; i++) {
				Row row = sheet.getRow(i);
				// id, function, chinese, english, thailand, model, zh_source, en_source,
				// th_source
				if (row != null) {
					List<String> contents = new ArrayList<>(3);
					VoiceRecord vr = new VoiceRecord();
					Cell idContent = row.getCell(0);
					vr.setId(this.getCellString(idContent));
					Cell functionContent = row.getCell(1);
					vr.setFunction(this.getCellString(functionContent));
					Cell chiness = row.getCell(2);
					contents.add(this.getCellString(chiness));
					Cell english = row.getCell(3);
					contents.add(this.getCellString(english));
					Cell thailand = row.getCell(4);
					contents.add(this.getCellString(thailand));
					Cell model = row.getCell(5);
					vr.setModel(this.getCellString(model));
					Cell zh_source = row.getCell(6);
					String zhSourceUrl = this.getCellString(zh_source);
					vr.getSources().get(0).setSources_url(zhSourceUrl);
					if (zhSourceUrl.trim().length() > 0) {
						needTransferFile.add(zhSourceUrl);
						String[] oldFilePath = zhSourceUrl.split("\\\\");
						String newFilePath = gconfig.getRemoteFileUrl() + File.separator
								+ oldFilePath[oldFilePath.length - 1];
						vr.getSources().get(0).setSources_url(newFilePath);
					}
					Cell en_source = row.getCell(7);
					String enSourceUrl = this.getCellString(en_source);
					vr.getSources().get(1).setSources_url(enSourceUrl);
					if (enSourceUrl.trim().length() > 0) {
						needTransferFile.add(enSourceUrl);
						String[] oldFilePath = enSourceUrl.split("\\\\");
						String newFilePath = gconfig.getRemoteFileUrl() + File.separator
								+ oldFilePath[oldFilePath.length - 1];
						vr.getSources().get(1).setSources_url(newFilePath);
					}
					Cell th_source = row.getCell(8);
					String thSourceUrl = this.getCellString(th_source);
					vr.getSources().get(2).setSources_url(thSourceUrl);
					if (thSourceUrl.trim().length() > 0) {
						needTransferFile.add(thSourceUrl);
						String[] oldFilePath = thSourceUrl.split("\\\\");
						String newFilePath = gconfig.getRemoteFileUrl() + File.separator
								+ oldFilePath[oldFilePath.length - 1];
						vr.getSources().get(2).setSources_url(newFilePath);
					}
					vr.setContent(contents);
					vr.setShowContent(contents.get(0));
					vrList.add(vr);
				}
			}
			this.transferFile(needTransferFile);
			return JsonResponseEntity.newSuccessJsonResult(vrList);
		} catch (IOException e) {
			logger.error(ThrowableUtil.getErrorInfoFromThrowable(e));
		}
		return null;
	}

	public void transferFile(ArrayList<String> needTransferFile) {
		if (needTransferFile.size() > 0) {
			int fileSize = needTransferFile.size();
			CountDownLatch cdl = new CountDownLatch(fileSize);
			for (int i = 0; i < fileSize; i++) {
				String oldFilePathVal = needTransferFile.get(i);
				String[] oldFilePath = oldFilePathVal.split("\\\\");
				final String newFilePath = gconfig.getLocalResourcePath() + File.separator
						+ oldFilePath[oldFilePath.length - 1];
				File oldFil = new File(oldFilePathVal);
				File newFile = new File(newFilePath);
				cachedPool.submit(() -> {
					try {
						Files.copy(oldFil, newFile);
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						cdl.countDown();
					}
				});
			}
			try {
				cdl.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public String getCellString(Cell cell) {
		if (cell != null) {
			cell.setCellType(Cell.CELL_TYPE_STRING);
			return cell.getStringCellValue();
		}
		return "";
	}

	@RequestMapping(value = "/userExcelImport", method = RequestMethod.POST)
	public JsonResponseEntity<Object> userExcelImport(@RequestParam(value = "file") MultipartFile excel) {
		if (excel == null) {
			return new JsonResponseEntity<>(ResultStatus.SYSTEM_EXP, "file is empty");
		}
		String fileName = excel.getOriginalFilename();
		String[] names = StringUtils.split(fileName, ".");
		Map<String, String> userInfo = new HashMap<>();
		try {
			InputStream input = excel.getInputStream();
			Workbook book = null;
			if (names != null && names.length > 1 && StringUtils.isNotEmpty(names[1])) {
				String fileType = names[1];
				if (excel2003L.equals(fileType)) {
					book = new HSSFWorkbook(input); // 2003-
				} else if (excel2007U.equals(fileType)) {
					book = new XSSFWorkbook(input); // 2007+
				}
			}
			if (book == null) {
				return new JsonResponseEntity<>(ResultStatus.SYSTEM_EXP, "unsport file");
			}
			// 得到第一个shell
			Sheet sheet = book.getSheetAt(0);
			// 得到Excel的行数
			int totalRows = sheet.getLastRowNum() + 1;
			for (int i = 0; i < totalRows; i++) {
				Row row = sheet.getRow(i);
				// id, function, chinese, english, thailand, model, zh_source, en_source,
				// th_source
				if (row != null) {
					Cell userId = row.getCell(0);
					String userNumStr = this.getCellString(userId);
					Cell userName = row.getCell(1);
					String userNameStr = this.getCellString(userName);
					userInfo.put(userNumStr, userNameStr);
				}
			}
			LotteryTurntableDataUtil.inputBasicInfo(userInfo);
			List<Map<String, String>> userList = new ArrayList<>(userInfo.size());
			userInfo.forEach((k, v) -> {
				Map<String, String> user = new HashMap<>();
				user.put("userCode", k);
				user.put("userName", v);
				user.put("show", "true");
				userList.add(user);
			});
			return JsonResponseEntity.newSuccessJsonResult(userList);
		} catch (IOException e) {
			logger.error(ThrowableUtil.getErrorInfoFromThrowable(e));
		}
		return null;
	}


}
